package org.termine.jsf;

import java.io.Serializable;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.model.ListDataModel;

import org.primefaces.model.SelectableDataModel;
import org.termine.entity.Service;
import org.termine.logic.ServiceManager;

@ManagedBean
@ViewScoped
public class ServiceJSF extends BaseJSF implements Serializable {

	private static final long serialVersionUID = 4823513814475319504L;

	@ManagedProperty(value = "#{serviceManager}")
	private ServiceManager serviceManager;
	@ManagedProperty(value = "#{loginJSF}")
	private LoginJSF loginJSF;

	private ServiceDataModel serviceDataModel;
	private Service selectedService;
	private Service newService;

	/*
	 * Init
	 */
	@PostConstruct
	public void init() {
		serviceDataModel = new ServiceDataModel(getServiceManager().getServicesForProvider(
				getLoginJSF().getPersonalData().getProvider_id()));
		newService = new Service();
	}

	/*
	 * Jsf Action Methods
	 */
	/*
	 * a new service - may NOT overlap with existing services with the same name - is
	 * only valid if start < end and start > now
	 */
	public String addService() {
		String result = getServiceManager().addService(newService,
				getLoginJSF().getPersonalData().getProvider_id());
		if (result.equals("SUCCESS")) {
			init();
			setInfoMessage("The service has been added successfully!");
			return "SUCCESS";
		} else if (result.equals("OVERLAP")) {
			setErrorMessage("The service could not be saved! It overlaps with an existing service.");
			return "ERROR";
		} else if (result.equals("START_AFTER_NOW") || result.equals("START_AFTER_END")) {
			setErrorMessage("The service could not be saved! The end must be after the start. Start must not lie in the past.");
			return "ERROR";
		} else {
			setFatalMessage("The service could not be saved! An error occured.");
			return "ERROR";
		}
	}

	/*
	 * a service can only be deleted, if it has no corresponding appointments
	 */
	public String deleteService() {
		String result = getServiceManager().deleteService(selectedService);
		if (result.equals("SUCCESS")) {
			init();
			setInfoMessage("The service has been deleted successfully!");
			return "SUCCESS";
		} else if (result.equals("APPOINTMENT_LOST")) {
			setErrorMessage("The service could not be deleted! An appointment has been booked for this service.");
			return "ERROR";
		} else {
			setFatalMessage("The service could not be deleted! An error occurred.");
			return "ERROR";
		}
	}

	/*
	 * TableModel
	 */
	public class ServiceDataModel extends ListDataModel<Service> implements
			SelectableDataModel<Service> {

		public ServiceDataModel() {
		}

		public ServiceDataModel(List<Service> data) {
			super(data);
		}

		@Override
		public Service getRowData(String rowKey) {
			@SuppressWarnings("unchecked")
			List<Service> services = (List<Service>) getWrappedData();

			for (Service service : services) {
				if (service.getService_id().equals(Integer.parseInt(rowKey))) {
					return service;
				}
			}
			return null;
		}

		@Override
		public Object getRowKey(Service service) {
			return service.getService_id();
		}
	}

	/*
	 * Getters & Setters
	 */
	public ServiceDataModel getServiceDataModel() {
		return serviceDataModel;
	}

	public void setServiceDataModel(ServiceDataModel serviceDataModel) {
		this.serviceDataModel = serviceDataModel;
	}

	public Service getSelectedService() {
		return selectedService;
	}

	public void setSelectedService(Service selectedService) {
		this.selectedService = selectedService;
	}

	public Service getNewService() {
		return newService;
	}

	public void setNewService(Service newService) {
		this.newService = newService;
	}

	public ServiceManager getServiceManager() {
		return serviceManager;
	}

	public void setServiceManager(ServiceManager serviceManager) {
		this.serviceManager = serviceManager;
	}

	public LoginJSF getLoginJSF() {
		return loginJSF;
	}

	public void setLoginJSF(LoginJSF loginJSF) {
		this.loginJSF = loginJSF;
	}

}
